/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.cvut.fel.taskpro.view.controller;

import cz.cvut.fel.taskpro.business.imanager.IAssignmentBusiness;
import cz.cvut.fel.taskpro.business.imanager.ISubjectBusiness;
import cz.cvut.fel.taskpro.business.imanager.IVersionBusiness;
import cz.cvut.fel.taskpro.business.support.BusinessRuleException;
import cz.cvut.fel.taskpro.business.support.TaskProException;
import cz.cvut.fel.taskpro.data.entity.AssignmentSubmit;
import cz.cvut.fel.taskpro.data.entity.AssignmentSubmit.State;
import cz.cvut.fel.taskpro.data.entity.Subject;
import cz.cvut.fel.taskpro.data.entity.VersionFile;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

/**
 * This controller is responsible for load recently submitted task and rate them.
 * Filters are also provided. The controller is view scoped and is called as 
 * assignSubmitBean.
 * @author Tom
 */
@ManagedBean(name = "assignSubmitBean")
@ViewScoped
public class SubmittedTask extends AbstractFileController implements Serializable {
    private List<Subject> kantorsSubjects;
    private List<String> selectedSubject;
    private Map<String, Subject> subjectMap;
    private List<AssignmentSubmit> assignmentSubmits;
    private AssignmentSubmit selectedAssignmentSubmit;
    private List<VersionFile> assignmentVersionsFile;
    private List<AssignmentSubmit.State> assignmentSubmitStates;
    private AssignmentSubmit.State[] assignmentSubmitSelectedStates;
    @EJB
    private IAssignmentBusiness assignmentB;
    @EJB
    private ISubjectBusiness subjectB;
    @EJB
    private IVersionBusiness versionB;
    /**
     * This mthod prepare controller to show submitted task. First variable for
     * filter are setted up and then is aked business layer for all subject which 
     * teach kantor. Then each subject is added to filter and then is business layer
     * asked for all recently submitted assignments. This assignments must have be in
     * submitted state.
     * @see ISubjectBusiness#getSubjectsByTeacher(cz.cvut.fel.taskpro.data.entity.Kantor) 
     * @see IAssignmentBusiness#getAssignmentSubmitsByKontext(cz.cvut.fel.taskpro.data.entity.Kantor, java.util.List, java.util.List) 
     */
    @PostConstruct
    public void init() {
        recognizeLogin();
        subjectMap = new HashMap<String, Subject>();
        selectedSubject = new ArrayList<String>();
        assignmentSubmitStates = new ArrayList<AssignmentSubmit.State>();
        assignmentSubmitStates.add(AssignmentSubmit.State.SUBMITTED);
        assignmentSubmitSelectedStates = assignmentSubmitStates.toArray(new AssignmentSubmit.State[assignmentSubmitStates.size()]);
        assignmentSubmitStates.add(AssignmentSubmit.State.ACCEPTED);
        assignmentSubmitStates.add(AssignmentSubmit.State.REJECTED);
        try {
            kantorsSubjects = subjectB.getSubjectsByTeacher(loggedKantor);
            Iterator itSub = kantorsSubjects.iterator();
            while (itSub.hasNext()) {
                Subject currSubject = (Subject) itSub.next();
                subjectMap.put(currSubject.getCode(), currSubject);
                selectedSubject.add(currSubject.getCode());
            }
            assignmentSubmits = assignmentB.getAssignmentSubmitsByKontext(loggedKantor, kantorsSubjects, Arrays.asList(assignmentSubmitSelectedStates));
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
    }
    /**
     * This method call {@linkplain SubmittedTask#rateTask() } rate task function
     * and set up state of rated task to accepted.
     */
    public void acceptTask(){
        selectedAssignmentSubmit.setStateOfTask(State.ACCEPTED);
        this.rateTask();
    }
        /**
     * This method call {@linkplain SubmittedTask#rateTask() } rate task function
     * and set up state of rated task to rejecteed.
     */
    public void rejectTask(){
        selectedAssignmentSubmit.setStateOfTask(State.REJECTED);
        this.rateTask();
    }   
    /**
     * This method ask business layer for rate selecte submitted assignment.
     * @see IAssignmentBusiness#rateTask(cz.cvut.fel.taskpro.data.entity.AssignmentSubmit) 
     */
    public void rateTask() {
        try {
            assignmentB.rateTask(selectedAssignmentSubmit);
            printSuccMessage("Task rate: ", "task was successfully rated");
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
        catch(TaskProException e){
        printErrMessage(e.getExceptionCode(), e.getErrorMessage());
        }       
    }
    /**
     * This method ask business layer to save evaluation of each version of selected
     * submitted assignment.
     * @see IVersionBusiness#updateVersion(java.util.List) 
     */
    public void saveEvaluationOfVersion() {
        try {
            versionB.updateVersion(assignmentVersionsFile);
            printSuccMessage("Version evaluation", "The version has been succesfuly evaluated.");
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
    }
    /**
     * This mehtod ask business layer for submitted assignment submit based filter
     * setting. 
     *@see IAssignmentBusiness#getAssignmentSubmitsByKontext(cz.cvut.fel.taskpro.data.entity.Kantor, java.util.List, java.util.List)  
     */
    public void applyFilter() {
        if (selectedSubject.isEmpty()) {
            assignmentSubmits = null;
            printSuccMessage("0000", "The filter has been setted up.");
            return;
        }
        List<Subject> filteredSubjects = new ArrayList<Subject>();
        Iterator selIterator = selectedSubject.iterator();
        while (selIterator.hasNext()) {
            filteredSubjects.add(subjectMap.get(selIterator.next()));
        }
        try {
            if (assignmentSubmitSelectedStates == null) {
                assignmentSubmits = null;
            } else {
                assignmentSubmits = assignmentB.getAssignmentSubmitsByKontext(loggedKantor, kantorsSubjects, Arrays.asList(assignmentSubmitSelectedStates));
            }
            printSuccMessage("0000", "The filter has been setted up.");
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }


    }
    /**
     * This method ask business layer for load all version which were submitted
     * with selected submitted assignment.
     * @see IVersionBusiness#getAllVersionFileByAssingment(cz.cvut.fel.taskpro.data.entity.AssignmentSubmit) 
     */
    public void loadVersions() {
        assignmentVersionsFile = versionB.getAllVersionFileByAssingment(selectedAssignmentSubmit);
    }

    public List<Subject> getKantorsSubjects() {
        return kantorsSubjects;
    }

    public void setKantorsSubjects(List<Subject> kantorsSubjects) {
        this.kantorsSubjects = kantorsSubjects;
    }

    public List<String> getSelectedSubject() {
        return selectedSubject;
    }

    public void setSelectedSubject(List<String> selectedSubject) {
        this.selectedSubject = selectedSubject;
    }

    public ISubjectBusiness getSubjectB() {
        return subjectB;
    }

    public void setSubjectB(ISubjectBusiness subjectB) {
        this.subjectB = subjectB;
    }

    public Map<String, Subject> getSubjectMap() {
        return subjectMap;
    }

    public void setSubjectMap(Map<String, Subject> subjectMap) {
        this.subjectMap = subjectMap;
    }

    public List<VersionFile> getAssignmentVersionsFile() {
        return assignmentVersionsFile;
    }

    public void setAssignmentVersionsFile(List<VersionFile> assignmentVersionsFile) {
        this.assignmentVersionsFile = assignmentVersionsFile;
    }

    public AssignmentSubmit getSelectedAssignmentSubmit() {
        return selectedAssignmentSubmit;
    }

    public void setSelectedAssignmentSubmit(AssignmentSubmit selectedAssignmentSubmit) {
        this.selectedAssignmentSubmit = selectedAssignmentSubmit;
    }

    public List<AssignmentSubmit> getAssignmentSubmits() {
        return assignmentSubmits;
    }

    public void setAssignmentSubmits(List<AssignmentSubmit> assignmentSubmits) {
        this.assignmentSubmits = assignmentSubmits;
    }

    public List<AssignmentSubmit.State> getAssignmentSubmitStates() {
        return assignmentSubmitStates;
    }

    public void setAssignmentSubmitStates(List<AssignmentSubmit.State> assignmentSubmitStates) {
        this.assignmentSubmitStates = assignmentSubmitStates;
    }

    public State[] getAssignmentSubmitSelectedStates() {
        return assignmentSubmitSelectedStates;
    }

    public void setAssignmentSubmitSelectedStates(State[] assignmentSubmitSelectedStates) {
        this.assignmentSubmitSelectedStates = assignmentSubmitSelectedStates;
    }
}
